package com.frog.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Json工具类
 */

public final class JsonUtil {


    /**
     * object to json，默认关闭循环引用，不然无法解析同一个list中的同一个引用对象
     */
    public static String toJsonString(Object object) {
        return JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * object to json use single quotes
     */
    public static String toJsonStringUseSingleQuotes(Object object) {
        return JSON.toJSONString(object, SerializerFeature.UseSingleQuotes);
    }

    /**
     * date to json, yyyy-MM-dd HH:mm:ss
     */
    public static String toJsonStringForDate(Date date) {
        return JSON.toJSONString(date, SerializerFeature.WriteDateUseDateFormat);
    }

    /**
     * json to object
     */
    public static Object parseJson(String json) {
        return JSON.parse(json);
    }

    /**
     * Object to json
     */
    public static String toJSONString(Object object) {
        try {
            if (object instanceof String) {
                return (String) object;
            } else if (object instanceof Integer) {
                return String.valueOf(object);
            } else if (object instanceof Long) {
                return String.valueOf(object);
            } else if (object instanceof Double){
                return String.valueOf(object);
            } else if (object instanceof Boolean){
                return String.valueOf(object);
            }else {
                return JSON.toJSONString(object);
            }
        } catch (Exception ex) {
            return null;
        }
    }


    /**
     * json to map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> parseJsonToMap(
            String json) {
        return (Map<String, Object>) JSON.parse(json);
    }

    /**
     * json to map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> parseJsonToStringMap(
            String json) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        return (Map<String, String>) JSON.parse(json);
    }

    /**
     * json to T type
     */
    public static <T> T parseJson(String json, Class<T> clazz) {
        try {
            return JSON.parseObject(json, clazz);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * json to jsonArray
     */
    public static JSONArray parseJsonArray(String json) {
        try {
            if (StringUtils.isEmpty(json)) {
                throw new NullPointerException(String.format("json %s is null", json));
            }
            return JSON.parseArray(json);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * jsonArray allAll
     */
    public static boolean jsonArrayAddAll(JSONArray souceJsonArray, JSONArray targetJsonArray) {
        try {
            if (souceJsonArray == null) {
                souceJsonArray = new JSONArray();
            }
            if (targetJsonArray != null && targetJsonArray.size() > 0) {
                souceJsonArray.add(targetJsonArray);
            }
            return true;
        } catch (Exception e) {
        }
        return false;
    }


    /**
     * json to list
     */
    public static <T> List<T> parseJsonToList(String json, Class<T> clazz) {
        try {
            return JSON.parseArray(json, clazz);
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static boolean isJsonArray(String json) {
        return json != null && json.trim().startsWith("[");
    }

    public static boolean isJsonObject(String json) {
        return json != null && json.trim().startsWith("{");
    }

    public static JSONObject fromObjectMap(Map<String, Object> map) {
        return new JSONObject(map);
    }


    public static Object json2Object(JSONObject json, Class pojo) throws Exception {
        // 首先得到pojo所定义的字段
        Field[] fields = pojo.getDeclaredFields();
        // 根据传入的Class动态生成pojo对象
        Object obj = pojo.newInstance();
        for (Field field : fields) {
            // 设置字段可访问（必须，否则报错）
            field.setAccessible(true);
            // 得到字段的属性名
            String name = field.getName();
            // 这一段的作用是如果字段在JSONObject中不存在会抛出异常，如果出异常，则跳过。
            try {
                json.get(name);
            } catch (Exception ex) {
                continue;
            }
            if (json.get(name) != null && !"".equals(json.getString(name))) {
                // 根据字段的类型将值转化为相应的类型，并设置到生成的对象中。
                if (field.getType().equals(Long.class) || field.getType().equals(long.class)) {
                    field.set(obj, Long.parseLong(json.getString(name)));
                } else if (field.getType().equals(String.class)) {
                    field.set(obj, json.getString(name));
                } else if (field.getType().equals(Double.class) || field.getType().equals(double.class)) {
                    field.set(obj, Double.parseDouble(json.getString(name)));
                } else if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) {
                    field.set(obj, Integer.parseInt(json.getString(name)));
                /*} else if(field.getType().equals(java.util.Date.class)){
                    field.set(obj, Date.Parse(json.getString(name)));*/
                } else {
                    continue;
                }
            }
        }
        return obj;
    }

}
